package org.hcyspartnoc.luoxin.service.user.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import jakarta.annotation.Resource;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.experimental.Accessors;
import org.hcyspartnoc.luoxin.common.core.AjaxResult;
import org.hcyspartnoc.luoxin.common.core.configuration.ContrapsychConfiguration;
import org.hcyspartnoc.luoxin.common.core.context.BaseContextHolder;
import org.hcyspartnoc.luoxin.common.enums.chat.ChatMessageStatusEnum;
import org.hcyspartnoc.luoxin.common.enums.chat.ChatMessageTypeEnum;
import org.hcyspartnoc.luoxin.common.enums.chat.ChatSenderTypeEnum;
import org.hcyspartnoc.luoxin.common.enums.user.UserContactTypeEnum;
import org.hcyspartnoc.luoxin.common.exception.asset.AssetVCounselorException;
import org.hcyspartnoc.luoxin.common.exception.system.SysUserException;
import org.hcyspartnoc.luoxin.common.exception.user.UserContactException;
import org.hcyspartnoc.luoxin.mapper.asset.AssetVirtualCounselorMapper;
import org.hcyspartnoc.luoxin.mapper.user.UserContactMapper;
import org.hcyspartnoc.luoxin.pojo.po.asset.AssetVirtualCounselorPo;
import org.hcyspartnoc.luoxin.pojo.po.chat.ChatMessagePo;
import org.hcyspartnoc.luoxin.pojo.po.chat.ChatSessionPo;
import org.hcyspartnoc.luoxin.pojo.po.chat.ChatSessionUserPo;
import org.hcyspartnoc.luoxin.pojo.po.user.UserContactPo;
import org.hcyspartnoc.luoxin.pojo.vo.chat.ChatCommonVo;
import org.hcyspartnoc.luoxin.pojo.vo.chat.ChatMessageVo;
import org.hcyspartnoc.luoxin.pojo.vo.chat.ChatSessionUserVo;
import org.hcyspartnoc.luoxin.service.chat.impl.ChatMessageServiceImpl;
import org.hcyspartnoc.luoxin.service.user.IUserContactService;
import org.hcyspartnoc.luoxin.utils.ChannelContextUtils;
import org.hcyspartnoc.luoxin.utils.LuoxinUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;
import java.util.Random;

@Service
public class UserContactServiceImpl extends ServiceImpl<UserContactMapper, UserContactPo>
        implements IUserContactService {
    @Resource
    private UserContactMapper userContactMapper;
    @Resource
    private AssetVirtualCounselorMapper assetVirtualCounselorMapper;
    @Resource
    private ContrapsychConfiguration contrapsychConfiguration;
    @Autowired
    private ChannelContextUtils channelContextUtils;
    @Autowired
    private ChatMessageServiceImpl chatMessageServiceImpl;

    @Override
    @Transactional
    public void apply(String contact) throws SysUserException, UserContactException, AssetVCounselorException {
        // 分别联系人类型
        char typeOfContact = contact.charAt(0);
        int id;
        try {
            id = Integer.parseInt(contact.subSequence(1, contact.length()).toString());
        } catch (Exception ignore) {
            throw new UserContactException(UserContactException.CONTACT_NOT_EXISTS);
        }
        switch (typeOfContact) {
            case 'U':
                throw new SysUserException(SysUserException.USER_NOT_EXISTS);
            case 'G':
                throw new UserContactException(UserContactException.GROUP_NOT_EXISTS);
            case 'R':
                throw new UserContactException(UserContactException.ROBOT_NOT_EXISTS);
            case 'V':
                sendApplyToVirtual(id);
                break;
        }
    }

    private void sendApplyToVirtual(Integer vCounselorId) throws AssetVCounselorException, UserContactException {
        // 检查虚拟咨询师是否存在
        AssetVirtualCounselorPo assetVirtualCounselorPo = assetVirtualCounselorMapper
                .selectOne(new LambdaQueryWrapper<>(AssetVirtualCounselorPo.class)
                        .eq(AssetVirtualCounselorPo::getId, vCounselorId));
        if (Objects.isNull(assetVirtualCounselorPo))
            throw new AssetVCounselorException(AssetVCounselorException.VIRTUAL_COUNSELOR_NOT_EXITS);
        // 检查是否已经建立关系
        if (userContactMapper.exists(new LambdaQueryWrapper<>(UserContactPo.class)
                .eq(UserContactPo::getContactId, vCounselorId)
                .eq(UserContactPo::getUserId, BaseContextHolder.getContext().getBaseCurrentUser().getId())))
            throw new UserContactException(UserContactException.RELATION_HAS_EXISTS);
        // 检查虚拟咨询师是否开放
        if (assetVirtualCounselorPo.getIsOpen().equals(false))
            throw new AssetVCounselorException(AssetVCounselorException.VIRTUAL_COUNSELOR_NOT_EXITS);
        // 将咨询师设置为用户好友
        UserContactPo userContactPo = new UserContactPo();
        userContactPo.setContactRemark(assetVirtualCounselorPo.getName());
        userContactPo.setContactType(UserContactTypeEnum.V_COUNSELOR.getCode());
        userContactPo.setUserId(BaseContextHolder.getContext().getBaseCurrentUser().getId());
        userContactPo.setContactId(vCounselorId);
        save(userContactPo);
        // 创建一个会话和消息，并通过ws发送给用户
        createVCSession(assetVirtualCounselorPo, userContactPo, BaseContextHolder.getContext().getBaseCurrentUser().getId());
    }

    public void createVCSession(AssetVirtualCounselorPo assetVirtualCounselorPo, UserContactPo userContactPo, Integer uid) {
        String[] openings = JSON.parseObject(assetVirtualCounselorPo.getOpenings(), String[].class);
        String opening = openings[new Random().nextInt(openings.length)];
        // 创建会话
        String sessionId = LuoxinUtils.generateSessionId('U' + uid.toString(),
                'V' + assetVirtualCounselorPo.getId().toString());
        ChatSessionPo chatSessionPo = new ChatSessionPo();
        chatSessionPo.setId(sessionId);
        chatSessionPo.setFreeChatTimes(contrapsychConfiguration.getChat().getDailyFree());
        chatSessionPo.setMessage(opening);
        Db.saveOrUpdate(chatSessionPo);
        // 创建用户会话关联
        ChatSessionUserPo chatSessionUserPo = new ChatSessionUserPo();
        chatSessionUserPo.setContactAvatar(assetVirtualCounselorPo.getAvatar())
                .setContactName(assetVirtualCounselorPo.getName())
                .setUserId(uid)
                .setSessionId(sessionId)
                .setContactId(userContactPo.getId());
        Db.save(chatSessionUserPo);
        // 创建消息
        ChatMessagePo chatMessagePo = new ChatMessagePo();
        chatMessagePo.setMessageContent(opening)
                .setMessageType(ChatMessageTypeEnum.ADD_FRIEND.getCode())
                .setContactId(userContactPo.getUserId())// 机器人设置的联系人id为用户的id
                .setSenderId(assetVirtualCounselorPo.getId())
                .setStatus(ChatMessageStatusEnum.HAS_SEND.getCode())
                .setSenderNickname(assetVirtualCounselorPo.getName())
                .setSenderType(ChatSenderTypeEnum.V_COUNSELOR.getCode())
                .setSessionId(sessionId);
        Db.save(chatMessagePo);
        // ws返回响应
        ChatCommonVo chatCommonVo = new ChatCommonVo();
        AddFriendWsVo addFriendWsVo = new AddFriendWsVo(BeanUtil.copyProperties(chatSessionUserPo, ChatSessionUserVo.class), chatMessageServiceImpl.chatMessagePoToVo(chatMessagePo));
        chatCommonVo.setMessageContent(addFriendWsVo)
                .setMessageType(ChatMessageTypeEnum.ADD_FRIEND)
                .setSessionId(sessionId);
        channelContextUtils.sendToUser(uid.toString(), JSON.toJSONString(AjaxResult.success(chatCommonVo)));
    }

    @Data
    @AllArgsConstructor
    @Accessors(chain = true)
    public static class AddFriendWsVo {
        private ChatSessionUserVo chatSessionUserVo;
        private ChatMessageVo chatMessageVo;
    }
}

